home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #1 / Amiga Plus 1995 #1.iso / animationen / retina_fli_ii / time_routines.c < prev    next >
C/C++ Source or Header  |  1994-12-13  |  5KB  |  177 lines

  1. /* time_routines.c
  2.    AmigaDos supplies us with a Delay() function we can use in our
  3.    programs which takes an argument in 1/50ths or 1/60ths of a second.
  4.    This is too coarse grained, and is dependent on which country the
  5.    Amiga is in.  A better way to wait a specified amount of time
  6.    is using the timer.device.
  7.    Copyright © 1993 Robert Poole
  8. */
  9.  
  10. #include <exec/types.h>
  11. #include <exec/io.h>
  12. #include <exec/memory.h>
  13. #include <devices/timer.h>
  14.  
  15. #include <clib/exec_protos.h>
  16. #include <clib/alib_protos.h>
  17. #include <clib/dos_protos.h>
  18.  
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21.  
  22. #include "time_routines.h"
  23.  
  24. struct timerequest *TimerIO = NULL;
  25. struct timerequest *TimeQueue[NUM_TIME_SLOTS];
  26. struct MsgPort *TimerPort = NULL;
  27.  
  28. /* int setup_timer(void)
  29.    sets up all the necessary stuff for the timer.device
  30.    returns TRUE if successful, FALSE otherwise */
  31.  
  32. int setup_timer(void)
  33. {
  34.   int i, j;
  35.  
  36.   /* message port for communicating with timer device */
  37.   TimerPort = CreateMsgPort();
  38.   if (TimerPort == NULL) {
  39.     return(FALSE);
  40.   }
  41.   /* our primary IO structure */
  42.   TimerIO = (struct timerequest *) CreateExtIO(TimerPort,
  43.                            sizeof(struct timerequest));
  44.   if (TimerIO == NULL) {
  45.     DeleteMsgPort(TimerPort);
  46.     return(FALSE);
  47.   }
  48.  
  49.   /* open the timer device and initialize it */
  50.   if (OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *) TimerIO,
  51.          0L)) {
  52.     DeleteMsgPort(TimerPort);
  53.     DeleteExtIO((struct IORequest *) TimerIO);
  54.     return(FALSE);
  55.   }
  56.  
  57.   /* set up a primitive queue structure so we can make multiple requests */
  58.   for (i = 0; i < NUM_TIME_SLOTS; i++) {
  59.     TimeQueue[i] = (struct timerequest *) AllocMem(sizeof(struct timerequest),
  60.                            MEMF_PUBLIC | MEMF_CLEAR);
  61.     if (TimeQueue[i] == NULL) {
  62.       if (i > 0) {
  63.     for (j = 0; j < i; j++) {
  64.       FreeMem((void *) TimeQueue[j], sizeof(struct timerequest));
  65.     }
  66.       }
  67.       CloseDevice((struct IORequest *) TimerIO);
  68.       DeleteMsgPort(TimerPort);
  69.       DeleteExtIO((struct IORequest *) TimerIO);
  70.       return(FALSE);
  71.     }
  72.  
  73.     *TimeQueue[i] = *TimerIO;
  74.   }
  75.  
  76.   /* success! */
  77.   return(TRUE);
  78. }
  79. /* end: setup_timer() */
  80.  
  81. /* void dispose_timer_resources(void)
  82.    deallocate any and all allocated timer resources */
  83.  
  84. void dispose_timer_resources(void)
  85. {
  86.   int i;
  87.  
  88.   CloseDevice((struct IORequest *) TimerIO);
  89.   DeleteMsgPort(TimerPort);
  90.   DeleteExtIO((struct IORequest *) TimerIO);
  91.   for (i = 0; i < NUM_TIME_SLOTS; i++) {
  92.     FreeMem((void *) TimeQueue[i], sizeof(struct timerequest));
  93.   }
  94. }
  95. /* end: dispose_timer_resources() */
  96.  
  97. /* void synchronous_wait(unsigned long secs, unsigned long microsecs)
  98.    wait for specified amount of time and then return */
  99.  
  100. void synchronous_wait(unsigned long secs, unsigned long microsecs)
  101. {
  102.   struct timeval tv_temp;
  103.  
  104.   tv_temp.tv_secs = secs;
  105.   tv_temp.tv_micro = microsecs;
  106.  
  107.   TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  108.   TimerIO->tr_time = tv_temp;
  109.  
  110.   DoIO((struct IORequest *) TimerIO);
  111. }
  112. /* end: synchronous_wait() */
  113.  
  114. /* void asynchronous_wait(unsigned long secs, unsigned long microsecs)
  115.    same as synchronous_wait(), except that it returns immediately
  116.    the program can then go about its business, then call
  117.    wait_asynch_finish() to wait for the timer request to finish */
  118.  
  119. void asynchronous_wait(unsigned long secs, unsigned long microsecs)
  120. {
  121.   struct timeval tv_temp;
  122.  
  123.   tv_temp.tv_secs = secs;
  124.   tv_temp.tv_micro = microsecs;
  125.  
  126.   TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  127.   TimerIO->tr_time = tv_temp;
  128.  
  129.   SendIO((struct IORequest *) TimerIO);
  130. }
  131. /* end: asynchronous_wait() */
  132.  
  133. /* void wait_asynch_finish(void)
  134.    wait for an asynchronously started timer request to finish */
  135.  
  136. void wait_asynch_finish(void)
  137. {
  138.   WaitIO((struct IORequest *) TimerIO);
  139. }
  140. /* end: wait_asynch_finish() */
  141.  
  142. /* void queue_asynch_wait(int slot, unsigned long secs, unsigned long microsecs)
  143.    queue a request to wait in the given slot */
  144.  
  145. void queue_asynch_wait(int slot, unsigned long secs, unsigned long microsecs)
  146. {
  147.   /* check first to make sure we're in a valid slot range */
  148.   if (slot > NUM_TIME_SLOTS) {
  149.     return;
  150.   }
  151.   /* send off a request */
  152.   TimeQueue[slot]->tr_node.io_Command = TR_ADDREQUEST;
  153.   TimeQueue[slot]->tr_time.tv_secs = secs;
  154.   TimeQueue[slot]->tr_time.tv_micro = microsecs;
  155.   SendIO((struct IORequest *) TimeQueue[slot]);
  156. }
  157. /* end: queue_asynch_wait() */
  158.  
  159. /* int queue_next_finish(void)
  160.    wait for the next event in the time queue to end */
  161.  
  162. int queue_next_finish(void)
  163. {
  164.   int i;
  165.   struct Message *timer_msg;
  166.  
  167.   WaitPort(TimerPort);
  168.   timer_msg = GetMsg(TimerPort);
  169.   /* match the next event to complete */
  170.   for (i = 0; i < NUM_TIME_SLOTS; i++) {
  171.     if (timer_msg == (struct Message *) TimeQueue[i]) {
  172.       return(i);
  173.     }
  174.   }
  175. }
  176. /* end: queue_next_finish() */
  177.